﻿#include"contact.h"
#include"SList.h"
#include<string.h>
void LoadContact(contact** con)	//传入指向通讯录的头指针的指针
{
	FILE* pf = fopen("contact.txt", "rb");
	//打开一个名为 "contact.txt" 的文件，以二进制只读模式打开，并将文件指针赋值给pf。
	if (pf == NULL)
	{			//文件指针不能为空
		perror("fopen error!\n");
		return;
	}
	//循环读取文件数据
	PeoInfo info;	//声明一个名为 info 的结构体变量，用于存储从文件中读取的单个联系人信息。
	while (fread(&info, sizeof(info), 1, pf))
	{
		SLTPushBack(con, info);
	}
	printf("历史数据导入通讯录成功！\n");
}
//在循环中，使用 fread 函数从文件中读取 sizeof(info) 大小的数据到 info 变量中，如果读取成功，则调用 SLTPushBack 函数将 info 中的信息添加到通讯录链表的末尾。

void InitContact(contact** con) {
	LoadContact(con);//把本地的通讯录数据导⼊到链表结构
}


void AddContact(contact** con)
{
	//传入指向通讯录的头指针的指针
	PeoInfo info;
	//声明一个名为 info 的结构体变量，用于存储联系人信息。
	printf("请输入姓名：\n");
	scanf("%s", info.name);
	printf("请输入性别：\n");
	scanf("%s", info.sex);
	printf("请输入年龄：\n");
	scanf("%d", &info.age);
	printf("请输入联系电话：\n");
	scanf("%s", info.tel);
	printf("请输入地址：\n");
	scanf("%s", info.addr);
	SLTPushBack(con, info);	//调用链表的尾插函数，储存联系人信息
	printf("插入成功！\n");
}


contact* FindByName(contact* con, char name[])
{
	//返回一个指向通讯录里联系人结构体的指针。该函数接受两个参数：一个指向通讯录头部的指针 con 和一个代表要查找的姓名的字符数组 name。
	contact* cur = con;	//定义一个指针cur指向联系人结构体指针
	while (cur)			//通过循环遍历整个通讯录链表
	{					//使用strcmp函数进行匹配
		if (strcmp(cur->data.name, name) == 0) {
			return cur;	//匹配成功返回指向当前联系人的指针
		}
		cur = cur->next;
	}
	return NULL;
}

void DelContact(contact** con)
{	//传入指向通讯录的头指针的指针
	char name[NAME_MAX];	//获取要删除的联系人的姓名
	printf("请输入要删除的用户姓名：\n");
	scanf("%s", name);
	contact* pos = FindByName(*con, name); //定义一个pos指针来接受找到的联系人地址
	if (pos == NULL)
	{
		printf("要删除的用户姓名不在，删除失败！\n");
		return;
	}
	SLTErase(con, pos);		//联系人存在则使用链表的SLTErase函数进行删除
	printf("删除成功！\n");
}


void ShowContact(contact* con) 	//传入一个指向通讯录头部的指针 con 
{
	printf("%-10s %-4s %-4s %15s %-20s\n", "姓名", "性别", "年龄", "联系电话", "地址");
	contact* cur = con;	//定义一个指针cur指向联系人结构体指针
	while (cur)			//通过循环遍历打印通讯录
	{
		printf("%-10s %-4s %-4d %15s %-20s\n",
			cur->data.name,
			cur->data.sex,
			cur->data.age,
			cur->data.tel,
			cur->data.addr);
		cur = cur->next;
	}
}

void FindContact(contact* con) 	//传入一个指向通讯录头部的指针 con 
{
	char name[NAME_MAX];	//获取要查找的联系人的姓名
	printf("请输入要查找的用户姓名：\n");
	scanf("%s", name);
	contact* pos = FindByName(con, name);	//通过FindByName函数来寻找
	if (pos == NULL)
	{
		printf("要查找的用户名不存在，查找失败！\n");
		return;
	}
	printf("查找成功！\n");
	printf("%-10s %-4s %-4d %15s %-20s\n",
		pos->data.name,
		pos->data.sex,
		pos->data.age,
		pos->data.tel,
		pos->data.addr);
}

void ModifyContact(contact** con)
{	//传入指向通讯录的头指针的指针
	char name[NAME_MAX];
	printf("请输入要修改的用户姓名：\n");
	scanf("%s", &name);
	contact* pos = FindByName(*con, name);
	if (pos == NULL)
	{
		printf("要修改的用户名不存在，修改失败！\n");
		return;
	}
	printf("请输入要修改的姓名：\n");
	scanf("%s", pos->data.name);
	printf("请输入要修改的性别：\n");
	scanf("%s", pos->data.sex);
	printf("请输入要修改的年龄：\n");
	scanf("%d", &pos->data.age);
	printf("请输入要修改的联系电话：\n");
	scanf("%s", pos->data.tel);
	printf("请输入要修改的地址：\n");
	scanf("%s", pos->data.addr);
	printf("修改成功！\n");
}


void SaveContact(contact* con)
{	//传入一个指向通讯录头部的指针 con 
	FILE* pf = fopen("contact.txt", "wb");
	//打开一个名为 "contact.txt" 的文件，以二进制写入模式打开，并将文件指针赋值给 pf。
	if (pf == NULL)
	{
		perror("fopen error!\n");
		return;
	}
	//将通讯录数据写⼊⽂件
	contact* cur = con;	//定义一个指针cur指向联系人结构体指针
	while (cur)
	{
		fwrite(&(cur->data), sizeof(cur->data), 1, pf);
		//在循环中，使用 fwrite 函数将当前联系人的数据写入文件。
		//&(cur->data) 是对当前联系人数据的地址的引用，
		//sizeof(cur->data) 表示要写入的数据大小，
		//1 表示要写入的数据项数量，pf 是文件指针，指定写入的目标文件。
		cur = cur->next;
	}
	printf("通讯录数据保存成功\n");
}


void DestroyContact(contact** con)
{	//传入指向通讯录的头指针的指针
	SaveContact(*con);
	//在通讯录销毁之前，先把历史数据保存到本地⽂件中contact.txt
	SListDesTroy(con);	//调用链表中的SListDesTroy函数来销毁通讯录
}